using System.Collections.Generic;
using AudioStudio;
using GameFramework.Battle.Core;
using Gameplay.PVE.Data;
using Gameplay.PVE.Utils;
using NpcFramework;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.UI;
using Yoozoo.Framework.Managers;
using Yoozoo.Gta.Common;
using Yoozoo.Libs;
using Yoozoo.Managers;
using Yoozoo.Gameplay.RTS;

namespace Gameplay.PVE.Entity
{
    public class BattleUnit:UnitBase
    {
        protected RenderComponent renderComponent;
        protected HudComponent hudComponent;
        protected BattleUnitLog logger;
        private float lifeTimeDecreaseHp;
        private int lastLifeTimeDecreaseHp;
        private int pauseCount;

        public override void Initialize(UnitData data)
        {
            pauseCount = 0;
            base.Initialize(data);
            data.battleUnit = this;
#if UNITY_EDITOR
            logger = gameObject.GetOrAddComponent<BattleUnitLog>();
            logger.Init(this);
#endif
            InitComponents();
            OnInitialize();
        }

        public void InitializeFromLua(UnitData data,GameObject obj)
        {
            base.Initialize(data);
            this.gameObject = obj;
            data.battleUnit = this;
#if UNITY_EDITOR
            logger = gameObject.GetOrAddComponent<BattleUnitLog>();
            logger.Init(this);
#endif
        }

        protected virtual void InitComponents()
        {
            if (Data.id != NpcDataManager.MainCharacterId)
            {
                AddComponent<BehaviorComponent>();
                AddComponent<SearchComponent>();
               
                AddComponent<ControlComponent>();
                AddComponent<BattleComponennt>();
                AddComponent<SkillDirectorComponennt>();
                if (PveResourceManager.Instance.IsReady)
                {
                    hudComponent = AddComponent<HudComponent>();
                }
            }
            if (Data.moveType != 1)
            {
                AddComponent<HangingMoveComponent>();
                AddComponent<BattleMoveComponent>();
            }
            else
            {
                AddComponent<TowerMoveComponent>();
            }
            renderComponent = AddComponent<RenderComponent>();
        }

        public void HideOrShowBloodBar()
        {
            hudComponent?.HideOrShowBloodBar();
        }

        public override void OtherResourceComplete()
        {
            base.OtherResourceComplete();
            hudComponent = AddComponent<HudComponent>();
            ((IComponent)hudComponent).OnInitialize(this);;
            ((IComponent)hudComponent).OnBirth();
        }

        protected override void OnBirth()
        {
            base.OnBirth();
            lifeTimeDecreaseHp = 0;
            lastLifeTimeDecreaseHp = 0;
        }

        public void SetHatredSource(BattleUnit source)
        {
            if (source == null)
            {
                return;
            }
            HatredSearchTransmitArg arg = ClassManager.Get<HatredSearchTransmitArg>();
            arg.source = source;
            Transmit(ETransmitType.HatredSearch,arg);
            ClassManager.Free(arg);
        }

        public override void SetHpChange(float change,bool ignoreShield = false)
        {
            if (change < 0 && Data.CurrentShield > 0 && !ignoreShield)
            {
                Data.CurrentShield = Data.CurrentShield + change;
                if (Data.CurrentShield < 0)
                {
                    Data.CurrentShield = 0;
                    Data.TotalShield = 0;
                }
            }
            else
            {
                Data.CurrentHp = Data.CurrentHp + change;
                if (Data.CurrentHp > Data.TotalHp)
                {
                    Data.CurrentHp = Data.TotalHp;
                }

                if (Data.CurrentHp < 0)
                {
                    Data.CurrentHp = 0;
                }
            }

            Transmit(ETransmitType.UpdateHp);
            ResidentHandler.Inst.GetFunction("pveManager.UpdateHeroHp").Action(Data.heroId, Data.CurrentHp,Data.TotalHp);
            if (Data.CurrentHp <= 0)
            {
                Dead();
            }
        }

        public override void SetMpChange(float change)
        {
            int value = Mathf.CeilToInt(change);
            Data.CurrentMp += value;
            if (Data.CurrentMp > Data.TotalMp)
            {
                Data.CurrentMp = Data.TotalMp;
            }

            if (Data.CurrentMp < 0)
            {
                Data.CurrentMp = 0;
            }
            Transmit(ETransmitType.UpdateMp);
            ResidentHandler.Inst.GetFunction("pveManager.UpdateHeroMp").Action(Data.heroId, Data.CurrentMp,Data.TotalMp,Data.mpCost);
        }
        
        

        public override void BeforeUpdate()
        {
            base.BeforeUpdate();
            renderComponent?.BeforeUpdate();
        }

        public override void Update()
        {
            base.Update();
            if (Data.lifeTime != 0 && !Data.isShowingSpawn)
            {
                float autoDecreaseHp = Data.TotalHp / Data.lifeTime * TimeManager.LogicDeltaTime;
                lifeTimeDecreaseHp += autoDecreaseHp;
                int decrease = Mathf.FloorToInt(lifeTimeDecreaseHp);
                int diff = decrease - lastLifeTimeDecreaseHp;
                if (diff > 0)
                {
                    lastLifeTimeDecreaseHp = decrease;
                    SetHpChange(-diff, true);
                }
            }

            if (PveGlobalVlues.MpAutoRecoverSpeed > 0)
            {
                SetMpChange(PveGlobalVlues.MpAutoRecoverSpeed * TimeManager.LogicDeltaTime);
            }
        }

        public override void Log(object content)
        {
            #if UNITY_EDITOR
                logger.AddToLog(content.ToString());
            #endif
        }

        public override void SetLayer(int layer)
        {
            //base.SetLayer(layer);
            renderComponent?.SetLayer(layer);
            hudComponent?.SetLayer(layer);
        }

        public override void SetHudLayer(int layer)
        {
            base.SetHudLayer(layer);
            hudComponent?.SetLayer(layer);
        }

        public override void SetVisible(bool visible)
        {
            renderComponent?.SetVisible(visible);
        }

        public override void LateUpdate()
        {
            base.LateUpdate();
            renderComponent?.LateUpdate();
        }

        public override void Play(string action,float speed = 1)
        {
            renderComponent?.Play(action);
            renderComponent?.SetAnimSpeed(speed);
        }

        public void SetIsStun(bool isStun)
        {
            renderComponent?.SetIsStun(isStun);
        }

        public override void PlaySkill(string action)
        {
            renderComponent?.PLaySkill(action);
        }

        public override void SetAnimatorSpeed(float speed)
        {
            renderComponent?.SetAnimSpeed(speed);
        }

        public override void Dead()
        {
            if (Data.isDead)
            {
                return;
            }

            if (Data.modelId == 10000)
            {
                //Transmit(ETransmitType.Dead);
            }
            else
            {
                Transmit(ETransmitType.Dead);
            }
            if (!string.IsNullOrEmpty(Data.config.death_voice))
            {
                AudioManager.PlayVoice(Data.config.death_voice,gameObject);
            }
            base.Dead();
            if (Data.team == 2)
            {
                /*if (Data.modelId == 9999) //直升机
                {
                    TimeManager.Instance.DelayCall(103 * 16, () =>
                    {
                        AudioManager.StopSound("sfx_rpg_helicopter_idle",gameObject);
                        AudioManager.PlaySound("sfx_rts_carblast",gameObject);
                        PveEffectManager.Instance.PlayEffect((int)ESkillEffect.explosive,Data.position,Vector3.forward,5,2);
                        PveCameraManager.Instance.Shake(0.5f);
                    });
                }*/
                /*else if (Data.modelId == 10000) // 小飞机
                {
                    AudioManager.PlaySound("sfx_rts_carblast",gameObject);
                    PveEffectManager.Instance.PlayEffect((int)ESkillEffect.explosive,Data.position + new Vector3(0,1,0),Vector3.forward,5,0.3f);
                }
                else if (Data.modelId == 10001) // 大飞机
                {
                    AudioManager.PlaySound("sfx_rts_carblast",gameObject);
                    PveEffectManager.Instance.PlayEffect((int)ESkillEffect.explosive,Data.position + new Vector3(0,1,0),Vector3.forward,5,2);
                }*/
                //else
                {
                    //if (PveManager.Instance.isInPve)
                    {
                        var go = PveEffectManager.Instance.PlayEffect2(100, Data.position, Data.forward);
                        var particals = go.GetComponentsInChildren<ParticleSystem>();

                        int usdCount = 0;
                        if (PveGlobalVlues.moneyCountRegion == Vector2.zero)
                        {
                            var moneyCount = PveGlobalVlues.moneyCount;
                            usdCount = moneyCount[Random.Range(0, moneyCount.Count)];
                        }
                        else
                        {
                            usdCount = Random.Range((int)PveGlobalVlues.moneyCountRegion.x,
                                (int)PveGlobalVlues.moneyCountRegion.y);
                        }

                        for (int i = 0; i < particals.Length; i++)
                        {
                            var burst = particals[i].emission.GetBurst(0);
                            burst.count = usdCount;
                            particals[i].emission.SetBurst(0,burst);
                        }
                        /* if (PveManager.Instance.isInPve)
                        {
                            var endPos =
                                PveCameraManager.Instance.uiCamera.WorldToScreenPoint(PveManager.Instance.AwardPosition);

                            var count = Random.Range(4, 8);
                            FlyAnimationMgr.GetInstance(nameof(FlyAnimationMgr)).RPGHangingDropFly(go,
                                endPos, count, (_go) =>
                                {
                                    PveResourceManager.RecoverResource(_go, PveResourceManager.EPveResType.SkillEffect, 100);
                                });
                        }*/
                    }
                }

            }
            SetMpChange(-Data.CurrentMp);
            if (Data.team == 0 && !Data.isSummonUnit)
            {
                PveCardManager.Instance.OnUnitDead(Data.id);
            }
            
        }

        protected override void Dispose()
        {
            renderComponent = null;
            hudComponent = null;
        }

        public override void FixedUpdate()
        {
            base.FixedUpdate();
            renderComponent?.OnFixedUpdate();
            hudComponent?.OnFixedUpdate();
        }

        public void Unscaled()
        {
            renderComponent?.Unscaled();
        }

        public void Scaled()
        {
            renderComponent?.Scaled();
        }

        public void Pause()
        {
            pauseCount++;
            Transmit(ETransmitType.Pause);
            renderComponent?.Pause();
        }

        public void Resume()
        {
            pauseCount--;
            if (pauseCount <= 0)
            {
                pauseCount = 0;
                Transmit(ETransmitType.Resume);
                renderComponent?.Resume();
            }
        }

        public void SetAnimatorBool(string name, bool value)
        {
            renderComponent?.SetAnimatorBool(name, value);
        }

        public override void SetDirection()
        {
            renderComponent?.SetDirection();
        }

        //交出自己的模型，并认为自己已经没有模型
        public GameObject GetModel()
        {
            return renderComponent?.GetModel();
        }

        public void Reset()
        {
            ((IClass)this).OnReset();
        }
    }
}
